Release 10.1A: OpenEdge Development:
Progress 4GL Reference


DEFINE PARAMETER statement

Defines a run-time parameter in a Progress subprocedure, Windows dynamic link library (DLL) routine, UNIX shared library routine, or ActiveX control event procedure.

Note: To define run-time parameters of a user-defined function, or a method within a class (including constructor methods), see the Parameter definition syntax reference entry in this book.

Each parameter requires its own DEFINE statement. The parameters must be specified in the RUN statement in the same order they are defined with DEFINE statements. In addition, the parameter types (INPUT, OUTPUT, INPUT-OUTPUT, RETURN, TABLE, TABLE-HANDLE, DATASET, DATASET-HANDLE, and BUFFER) specified in the DEFINE and RUN statements must agree. The corresponding data types and run-time values must also be compatible enough to allow Progress to perform any necessary conversions.

Syntax

DEFINE { INPUT | OUTPUT | INPUT-OUTPUT | RETURN } 
  PARAMETER parameter
  {  AS [ HANDLE TO ] datatype 
   | AS [ CLASS ] { type-name }
   | LIKE field }
  [ EXTENT [ expression ] ] 
  [ [ NOT ] CASE-SENSITIVE ]
  [ FORMAT string ]
  [ DECIMALS n ]
  [ INITIAL constant ]
  [ COLUMN-LABEL label ]
  [ LABEL string ]
  [ NO-UNDO ] 

DEFINE PARAMETER BUFFER buffer FOR table
  [ PRESELECT ]
  [ LABEL label ] 

DEFINE { INPUT | OUTPUT | INPUT-OUTPUT } PARAMETER
  {   TABLE FOR temp-table-name [ APPEND ] [ BIND ]
    | TABLE-HANDLE temp-table-handle [ APPEND ] [ BIND ]
    | DATASET FOR dataset-name [ APPEND ] [ BIND ]
    | DATASET-HANDLE dataset-handle [ APPEND ] [ BIND ]
  } 

INPUT PARAMETER

Defines a parameter that gets its value from one of the following sources:

OUTPUT PARAMETER

Defines a parameter that returns a value to one of the following destinations:

INPUT-OUTPUT PARAMETER

Defines a parameter that receives an initial value passed from the calling procedure that can be subsequently modified by the called procedure. The calling procedure cannot pass a literal value. The called procedure returns the modified value to one of the following destinations:

RETURN PARAMETER

Defines a parameter that holds the return value of a DLL or UNIX shared library routine. When the DLL routine returns, the value of this parameter is passed back to the calling procedure. You can only have one RETURN parameter per routine.

parameter

Identifies the name of the parameter you want to define.

AS [ HANDLE TO ] datatype

Specifies the data type of the parameter.

For Progress subprocedures, datatype can specify any built-in Progress data type used to define variables. For more information, see the reference entry for the DEFINE VARIABLE statement.

For DLL or UNIX shared library routines, datatype can specify a Progress DLL data type. Progress DLL data types include the built-in Progress data types CHARACTER and MEMPTR, Windows DLL-equivalent data types, and UNIX shared library data types.

Table 26 shows how Windows DLL and UNIX shared library data types map to Progress DLL data types.

Table 26: Data types for DLL and UNIX shared library routine parameters
Example C
data type
Progress DLL parameter
data type
Windows DLL and UNIX shared library data type
char 
BYTE 
8-bit unsigned integer
short 
SHORT 
16-bit signed integer
unsigned short 
UNSIGNED-SHORT 
16-bit unsigned integer
long, int1 
LONG2  
32-bit signed integer
float 
FLOAT 
4-byte floating point
double 
DOUBLE 
8-byte floating point
char* 
CHARACTER 
Address (usually 32 bits)
c-data-type3 
HANDLE TO 
parameter-data-type3 
Address (usually 32 bits)
char*, output-pointer (which can be char**, short**, and so on), or a pointer to a structure.
MEMPTR 
Address (usually 32 bits)
  1. The C data type int generally specifies a size that depends on the operating system.
  2. To pass a NULL pointer value to a DLL routine, pass 0 using a LONG parameter. Do not use a null MEMPTR variable to pass a NULL value. However, you can pass a NULL value in one or more elements of a MEMPTR array. If this conflicts with another way to call the DLL routine, specify a second declaration for the same routine using the ORDINAL option of the PROCEDURE statement.
  3. You can use the HANDLE TO option to specify a pointer to a scalar type. Therefore, you can use the HANDLE TO option with the parameter data types (that is, BYTE, SHORT, UNSIGNED-SHORT, LONG, FLOAT, and DOUBLE) in order to specify a pointer to the respective C data types (that is, char, short, unsigned short, long, int, float, and double). For a CHARACTER or MEMPTR parameter, it is redundant because this data type is always passed using a pointer (char*).

Caution: For CHARACTER parameters, Progress always passes the routine a pointer to the character or character string value rather than the value itself. If the routine modifies the value, it can also modify Progress memory outside the bounds of the CHARACTER value with unpredictable results. For this reason, Progress does not allow you to use OUTPUT or RETURN for CHARACTER or LONGCHAR parameters, as well as CHARACTER or LONGCHAR array parameters, and does not recommend you use INPUT-OUTPUT for CHARACTER or LONGCHAR parameters. Rather, pass the character string as a MEMPTR parameter. For more information, see OpenEdge Development: Programming Interfaces .

Note: You cannot use RETURN for any type of array parameter.

To indicate that the DLL or UNIX shared library parameter is a pointer to a value rather than the value itself, use the HANDLE option. The HANDLE option is required when the DLL routine expects a pointer to the value. Note that the CHARACTER data type implies the HANDLE option, whether or not you specify it. The TO keyword aids readability but has no meaning.

For ActiveX control event procedures, datatype can specify the built-in Progress data type that maps to the COM object data type of an ActiveX event parameter. Table 27 shows how the COM object data types for event parameters (shown as ActiveX data types) map to Progress data types.

Table 27: Data types for ActiveX control event procedures
ActiveX data type1
Progress data type
Array
Progress array variable
Array of bytes
RAW
Boolean (2-byte integer)
LOGICAL
Byte (unsigned byte)
INTEGER
Currency (8-byte integer with fixed decimal point)
DECIMAL
Date
Double
DATE
DATETIME
DATETIME-TZ
Decimal
DECIMAL
Double (8-byte floating point)
DECIMAL
Error Code
INTEGER
Integer (2-byte integer)
INTEGER
Long (4-byte integer)
INTEGER
Object (32-bit value)
COM-HANDLE
String (character string type)
CHARACTER
LONGCHAR
Unsigned Byte
INTEGER
Unsigned Long (4-byte integer)
INTEGER
Unsigned Short (2-byte integer)
INTEGER
Variant (variable type)
<ANYTYPE>2
  1. For more information on these data type implementations for COM objects, see OpenEdge Development: Programming Interfaces .
  2. For Variant event parameters, the AppBuilder specifies <ANYTYPE> as a place holder. You must change <ANYTYPE> to the data type that most closely matches the expected value. For more information, see the available documentation on the event parameter.

AS [ CLASS ] { type-name }

Defines a class or interface parameter. Progress passes the object reference for a class or interface parameter (by value), not the class or interface itself.

type-name

A character string that specifies the type name of a class or interface. Specify a type name using the package.class-name syntax as described in the Type-name syntax reference entry in this book.

If the specified class or interface type name conflicts with an abbreviation of a built-in Progress data type name, such as INT for INTEGER, you must specify the CLASS keyword.

LIKE, CASE SENSITIVE, FORMAT, DECIMALS, INITIAL, COLUMN-LABEL, LABEL, NO-UNDO

For descriptions of these options, see the DEFINE VARIABLE statement reference entry.

EXTENT [ expression ]

Defines a determinate array parameter (which has a defined number of elements) or an indeterminate array parameter (which has an undefined number of elements). To define a determinate array parameter, specify the EXTENT option with the expression argument. This optional argument evaluates to an integer value that represents an extent for the array parameter. To define an indeterminate array parameter, specify the EXTENT option without the expression argument. Progress determines the size of indeterminate array parameters at runtime.

You can pass a determinate array or indeterminate array to a procedure or function that declares the parameter as an indeterminate array. You cannot pass an indeterminate array to a procedure or function that declares the parameter as a determinate array. If you call a procedure or function that fixes the number of elements in an indeterminate array, Progress treats the fixed indeterminate array as a determinate array.

You cannot pass an indeterminate array to a COM object, DLL routine, or UNIX shared library routine.

If you want to define a parameter that is like an array variable or field, using the LIKE option, but you do not want the parameter to be an array, you can use EXTENT 0 to indicate a non-array parameter.

If you are using the AS datatype option and you do not use the EXTENT option (or you specify expression as 0), the parameter is not an array parameter. If you are using the LIKE field option and you do not use the EXTENT option, the parameter uses the extent defined for the database field you name (if any).

PARAMETER BUFFER buffer FOR table [ PRESELECT ] [ LABEL label ]

Defines a buffer parameter. You can pass a buffer associated with a database table to a buffer parameter. You cannot pass a work table to a buffer parameter. A buffer parameter is always INPUT-OUTPUT. You cannot pass buffer parameters to the AppServer.

For descriptions of the PRESELECT and LABEL options, see the DEFINE BUFFER statement reference entry.

TABLE FOR temp-table-name

Defines a temporary table parameter.

You can pass a temporary table parameter to both local and remote procedures. Progress passes the parameter by value, by default. That is, the calling routine and the called routine each have their own instance of the temporary table. When you invoke the RUN statement, Progress deep-copies the temporary table from one routine’s instance to the other routine’s instance. Which table travels depends on whether the parameter is INPUT, OUTPUT, or INPUT-OUTPUT. When you pass a temporary table as an INPUT parameter, Progress overlays the stationary instance with the traveling table, by default. You can also append the traveling table to the end of the stationary instance by specifying the APPEND option. For more information about the APPEND option, see the option description below.

When passing a temporary table parameter to a local procedure, you can override the default by passing the parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). Passing a temporary table parameter by reference or by binding allows the calling routine and the called routine to access the same object instance (instead of deep-copying the parameter).

Note: When you specify the BIND option in the DEFINE PARAMETER statement, you must also specify the BIND option in the RUN statement.

For more information about passing a temporary table parameter by reference or by binding, see the Parameter passing syntax reference entry in this book. For more information about temporary table parameters, see OpenEdge Development: Progress 4GL Handbook .

TABLE-HANDLE temp-table-handle

Defines a temporary table handle parameter.

DATASET dataset-name

Defines a static ProDataSet object parameter.

You can pass a ProDataSet object parameter to both local and remote procedures. Progress passes the parameter by value, by default. That is, the calling routine and the called routine each have their own instance of the object. When you invoke the RUN statement, Progress deep-copies the object from one routine’s instance to the other routine’s instance. Which object travels depends on whether the parameter is INPUT, OUTPUT, or INPUT-OUTPUT. When you pass a ProDataSet object as an INPUT parameter, Progress overlays the stationary instance with the traveling ProDataSet object, by default. You can also append the traveling ProDataSet object to the end of the stationary instance by specifying the APPEND option. For more information about the APPEND option, see the option description below.

When passing a ProDataSet object parameter to a local procedure, you can override the default by passing the parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). Passing a ProDataSet object parameter by reference or by binding allows the calling routine and the called routine to access the same object instance (instead of deep-copying the parameter).

Note: When you specify the BIND option in the DEFINE PARAMETER statement, you must also specify the BIND option in the RUN statement.

For more information about passing a ProDataSet object parameter by reference or by binding, see the Parameter passing syntax reference entry in this book. For more information on ProDataSet object parameters, see OpenEdge Development: Progress 4GL Handbook .

DATASET-HANDLE dataset-handle

Defines a ProDataSet object handle parameter.

FOR ... APPEND

Specifies whether or not to append the traveling temporary table data to the stationary temporary table instance. To append input parameter data, specify the APPEND option in the DEFINE PARAMETER statement. To append output parameter data, specify the APPEND option in the RUN statement.

For temp-table-name, FOR is required and APPEND is optional.

For temp-table-handle, both FOR and APPEND are optional and are used together. Without the FOR keyword, the temporary table handle is local to the called procedure - it is created when the procedure starts and deleted when the procedure completes. Therefore, there is nothing to APPEND the received parameter to. When the FOR keyword is used, the temporary table handle is defined at a higher level outside the called procedure and continues to exist after the called procedure completes.

BIND

Indicates that a TABLE, TABLE-HANDLE, DATASET, or DATASET-HANDLE parameter binds a reference-only object in one routine to an object instance defined and instantiated in another local routine.

When you define a reference-only object in the calling routine, and you want to bind that object definition to an object instance in the called routine, define the parameter by specifying the BIND option in an INPUT or INPUT-OUTPUT parameter definition. When you define a reference-only object in the called routine, and you want to bind that object definition to an object instance in the calling routine, define the parameter by specifying the BIND option in an OUTPUT parameter definition. In either case, the reference-only object definition remains bound to the object instance until the routine containing the reference-only object definition is deleted or terminates.

Caution: Do not delete the object or routine to which a reference-only object is bound, or you might be left with references to an object that no longer exists.

You can bind multiple reference-only object definitions to the same object instance. You can also bind a single reference-only object definition to the same object instance multiple times without generating an error. However, you cannot bind a single reference-only object definition to multiple object instances.

When passing one of these parameters to a remote procedure, Progress ignores the BIND option and deep-copies the parameter based on the specified parameter mode.

For more information about passing these parameters by binding, see the Parameter passing syntax reference entry in this book.

Examples

In the following examples, the r-runpar.p procedure runs a subprocedure called r-param.p and passes the subprocedure an INPUT parameter. The subprocedure r-param.p displays the INPUT parameter.

r-runpar.p
RUN r-param.p (INPUT 10). 

r-param.p
DEFINE INPUT PARAMETER int-param AS INTEGER.
DISPLAY int-param LABEL "Integer input param"
  WITH SIDE-LABELS. 

In the following example, the r-runpr1.p procedure runs a subprocedure called r-param1.p. This example illustrates the use of multiple parameters and shows that the parameters must be passed in the proper order and must be of the same data type. Note that if you do not specify a parameter type in the RUN statement, Progress assumes it is an input parameter.

r-runpr1.p
DEFINE VARIABLE new-param AS CHARACTER FORMAT "x(20)".
DEFINE VARIABLE out-param AS DECIMAL.
DEFINE VARIABLE in-param AS INTEGER INIT 20.
RUN r-param1.p (OUTPUT out-param, 10, OUTPUT new-param, in-param).
DISPLAY out-param LABEL "Updated YTD Sales" SKIP 
    new-param LABEL "Status" 
    WITH SIDE-LABELS. 

r-param1.p
DEFINE OUTPUT PARAMETER xout-param AS DECIMAL.
DEFINE INPUT PARAMETER newin AS INTEGER.
DEFINE OUTPUT PARAMETER xnew-param AS CHARACTER.
DEFINE INPUT PARAMETER xin-param AS INTEGER.

FOR EACH customer:
   xout-param = balance + xout-param.
END.

DISPLAY xout-param LABEL "Balance" WITH SIDE-LABELS.
xout-param = xout-param + newin + xin-param.
xnew-param = "Example Complete". 

In the following example, the r-runpr2.p procedure displays information from a database table and assigns the value of a database field to a variable called io-param. The variable is passed as an INPUT-OUTPUT parameter to a subprocedure called r-param2.p. The subprocedure r-param2.p performs a calculation on the INPUT-OUTPUT parameter, then passes it back to the main procedure. The r-runpr2.p assigns the value io-param to a database field, then displays io-param.

r-runpr2.p
DEFINE VARIABLE io-param AS INTEGER.

FOR EACH item:
  DISPLAY Item-name On-hand WITH 1 DOWN.
  io-param = Item.On-hand.
  RUN r-param2.p (INPUT-OUTPUT io-param).
  Item.On-hand = io-param.
  DISPLAY io-param LABEL "New Quantity On-hand".
END. 

r-param2.p
DEFINE INPUT-OUTPUT PARAMETER io-param AS INTEGER.
DEFINE VARIABLE inp-qty AS INTEGER.
PROMPT-FOR inp-qty LABEL "Quantity Received?".
ASSIGN inp-qty.
io-param = io-param + inp-qty. 

The following example uses a buffer parameter. The procedure r-bufp.p passes the Customer buffer to r-fincus.p. The r-fincus.p procedure then attempts to find a record using that buffer.

r-bufp.p
DEFINE BUTTON find-butt LABEL "Find Customer".

ENABLE find-butt Customer.Cust-num WITH FRAME cust-frame.

ON CHOOSE OF find-butt
  DO: 
     RUN r-fincus.p(INPUT Customer.Cust-num:HANDLE IN FRAME cust-frame,
                    BUFFER Customer). 
     DISPLAY Customer WITH FRAME cust-frame.
  END.

ON ENTRY OF Customer.Cust-num
  HIDE MESSAGE.
  
WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW.   

r-fincus.p
DEFINE INPUT PARAMETER  wid-hand  AS WIDGET-HANDLE.
DEFINE PARAMETER BUFFER curr-buff FOR Customer.

FIND curr-buff WHERE curr-buff.Cust-num = 
                     INT(wid-hand:SCREEN-VALUE) NO-ERROR.

IF NOT AVAILABLE(curr-buff)
THEN DO:
   MESSAGE "Record not found.".
   RETURN ERROR.
END. 
   
RETURN. 

The following example defines parameters for the DLL routine, MessageBox(), which displays a message on the screen:

r-dllex1.p
DEFINE VARIABLE result AS INTEGER.

MESSAGE "  It’s a whole new world!"
  VIEW-AS
    ALERT-BOX MESSAGE
    BUTTONS OK
    TITLE "Progress Message".

RUN MessageBoxA (0, "  It’s a whole new world, again!!", 
      "Progress DLL access", 0, OUTPUT result).

PROCEDURE MessageBoxA EXTERNAL "user32.dll":
  DEFINE INPUT PARAMETER hwnd AS LONG.
  DEFINE INPUT PARAMETER mbtext AS CHARACTER.
  DEFINE INPUT PARAMETER mbtitle AS CHARACTER.
  DEFINE INPUT PARAMETER style AS LONG.
  DEFINE RETURN PARAMETER result AS LONG.
END. 

Notes

See also

DEFINE BUFFER statement, DEFINE VARIABLE statement, DELETE PROCEDURE statement, RUN statement


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095